package se.webbzon.boltzmann.editor.list;

import java.util.ArrayList;
import java.util.Collection;
import java.util.Iterator;

import javax.swing.AbstractListModel;

public class NullableListModel<T> extends AbstractListModel<T> implements Iterable<T> {

	// Auto generated serial version UID
	private static final long serialVersionUID = 2385275297881353408L;

	// The list model
	private final ArrayList<T> model;

	/*============================================================
	Constructors
	============================================================*/
	
	/** Created a new empty nullable list model. **/
	public NullableListModel() {
		this(null);
	}
	
	/** Created a new nullable list model with a given content. **/
	public NullableListModel(Collection<T> collection) {
		model = new ArrayList<T>();
		
		if (collection != null)
			model.addAll(collection);
	}
	
	/*============================================================
	Public Methods
	============================================================*/
	
	/** Adds a new element to the nullable list model. **/
	public boolean addElement(T element) {
		if (model.add(element)) {
			fireContentsChanged(this,1,getSize());
			return true;
		} else
			return false;
	}
	
	/** Adds a collection of new elements to the nullable list model. **/
	public boolean addAllElements(Collection<? extends T> elements) {
		if (model.addAll(elements)) {
			fireContentsChanged(this,1,getSize());
			return true;
		} else
			return false;
	}
	
	/** Clears the content of the nullable list model. **/
	public void clearElements() {
		model.clear();
		fireContentsChanged(this,1,getSize());
	}
	
	/** Returns true if the given element was found in the nullable list model. **/
	public boolean containsElement(T element) {
		if (element == null)
			return true;
		else
			return model.contains(element);
	}
	
	/** Returns the first element in the nullable list model. **/
	public T firstElement() {
		return null;
	}
	
	/** Returns the last element in the nullable list model. **/
	public T lastElement() {
		if (model.isEmpty())
			return null;
		else
			return model.get(getSize()-2);
	}
	
	@Override public T getElementAt(int index) {
		if (index == 0)
			return null;
		else
			return model.get(index-1);
	}

	@Override public int getSize() {
		return model.size()+1;
	}

	@Override public Iterator<T> iterator() {
		return model.iterator();
	}
	
	/** Removes the element in the nullable list model with the given index. **/
	public void removeElement(int index) {
		if (index > 0) {
			model.remove(index-1);
			fireContentsChanged(this,index,getSize());
		}
	}
	
	/** Removes the given element from the nullable list model. **/
	public void removeElement(T element) {
		model.remove(element);
		fireContentsChanged(this,1,getSize());
	}

}
